﻿using HECore.SerilogWebApi.Extensions;
using Serilog;
using Serilog.Context;
using Serilog.Events;
using System.Net;

namespace HECore.SerilogWebApi.Extensions
{
    /// <summary>
    /// ApplicationBuilder 扩展
    /// </summary>
    public static class ApplicationBuilderExtensions
    {
        /// <summary>
        ///  添加使用Serilog请求日志
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseSerilogRequestLogging(this IApplicationBuilder app)
        {
            //允许body重用
            app.Use(next => context =>
            {
                context.Request.EnableBuffering();
                return next(context);
            });

            // 添加使用Serilog记录请求日志
            app.UseSerilogRequestLogging(options =>
            {
                // 请求日志输出模板
                options.MessageTemplate = "\n[R] {RequestMethod}={_RequestPath} | Status={StatusCode} | Time={Elapsed}ms\n[R] Req={_RequestBody} | Res={_ResponseBody}";

                // 发出调试级别事件而不是默认事件，将请求日志记录到:Debug日志
                options.GetLevel = (httpContext, elapsed, ex) => LogEventLevel.Debug;

                // 将其他属性附加到请求完成事件，将请求属性附加可以在模板中使用
                options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
                {
                    diagnosticContext.Set("_RequestPath", WebUtility.UrlDecode(httpContext.Request.Path + httpContext.Request.QueryString));

                    //请求body
                    var requestContent = "";
                    var method = httpContext.Request.Method.ToLower();
                    if (method == "post" || method == "put")
                    {
                        httpContext.Request.Body.Position = 0;
                        var requestReader = new StreamReader(httpContext.Request.Body);
                        requestContent = requestReader.ReadToEnd();
                    }
                    diagnosticContext.Set("_RequestBody", requestContent);
                    diagnosticContext.Set("_Service",AppDomain.CurrentDomain.FriendlyName);
                };
            });

            return app;
        }
    }
}
